package icu.makka.yygh.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import icu.makka.yygh.cmn.client.DictFeignClient;
import icu.makka.yygh.common.exception.CustomException;
import icu.makka.yygh.model.hosp.Hospital;
import icu.makka.yygh.model.hosp.HospitalSet;
import icu.makka.yygh.repository.HospitalRepository;
import icu.makka.yygh.result.ResultCodeEnum;
import icu.makka.yygh.service.HospitalService;
import icu.makka.yygh.service.HospitalSetService;
import icu.makka.yygh.vo.hosp.HospitalQueryVo;
import icu.makka.yygh.vo.order.SignInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class HospitalServiceImpl implements HospitalService {

    @Autowired
    private HospitalRepository hospitalRepository;

    @Autowired
    private DictFeignClient dictFeignClient;

    @Autowired
    private HospitalSetService hospitalSetService;

    /**
     * 医院列表
     * @param page
     * @param limit
     * @param hospitalQueryVo
     * @return
     */
    @Override
    public Page<Hospital> selectHospPage(Integer page, Integer limit, HospitalQueryVo hospitalQueryVo) {
        log.info("业务层，医院列表");

        //将vo对象转化为pojo类型
        Hospital hospital = new Hospital();
        BeanUtils.copyProperties(hospitalQueryVo, hospital);
        //创建Pageable对象
        Pageable pageable = PageRequest.of(page - 1, limit);
        //构造查询条件
        ExampleMatcher exampleMatcher = ExampleMatcher.matching()
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
                .withIgnoreCase(true);
        Example<Hospital> example = Example.of(hospital, exampleMatcher);
        //调用repository层
        Page<Hospital> hospitalPage = hospitalRepository.findAll(example, pageable);

        hospitalPage.getContent().stream().forEach(item -> {
            //完善医院信息
            setHospitalData(item);
        });

        //返回结果
        return hospitalPage;
    }

    /**
     * 更新医院上线状态
     * @param id
     * @param status
     */
    @Override
    public void updateStatus(String id, Integer status) {
        log.info("业务层，更新医院上线状态");

        Hospital hospital = hospitalRepository.findById(id).get();
        hospital.setStatus(status);
        hospital.setUpdateTime(new Date());
        hospitalRepository.save(hospital);
    }

    /**
     * 医院详细信息
     * @param id
     * @return
     */
    @Override
    public Map<String, Object> getHospById(String id) {
        log.info("业务层，医院详细信息，id={}", id);

        //根据id查询医院基本信息
        Hospital hospital = hospitalRepository.findById(id).get();
        //完善医院信息
        setHospitalData(hospital);
        //将数据添加到map集合
        Map<String, Object> map = new HashMap<>();
        map.put("hospital", hospital);
        map.put("bookingRule", hospital.getBookingRule());

        //返回结果
        return map;
    }

    /**
     * 医院详细信息
     * @param hoscode
     * @return
     */
    @Override
    public Map<String, Object> item(String hoscode) {
        log.info("业务层，医院详细信息，hoscode={}", hoscode);

        //根据医院编号查询医院基本信息
        long start = System.currentTimeMillis();
        Hospital hospital = hospitalRepository.findHospitalByHoscode(hoscode);
        long end = System.currentTimeMillis();
        log.info("从mongodb中查询医院基本信息，耗时:{}ms", end - start);
        
        //完善医院信息
        setHospitalData(hospital);
        //将数据添加到map集合
        Map<String, Object> map = new HashMap<>();
        map.put("hospital", hospital);
        map.put("bookingRule", hospital.getBookingRule());

        //返回结果
        return map;
    }

    /**
     * 获取医院签名信息
     * @param hoscode
     * @return
     */
    @Override
    public SignInfoVo getSignInfoVo(String hoscode) {
        log.info("获取医院签名信息");

        //创建最终返回的对象
        SignInfoVo signInfoVo = new SignInfoVo();
        //根据医院编号查询医院信息
        LambdaQueryWrapper<HospitalSet> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(!StringUtils.isEmpty(hoscode), HospitalSet::getHoscode, hoscode);
        HospitalSet hospitalSet = hospitalSetService.getOne(queryWrapper);
        //如果查询为空，抛出参数异常
        if (null == hospitalSet) {
            throw new CustomException(ResultCodeEnum.PARAM_ERROR);
        }
        //获取医院签名和api_url
        String signKey = hospitalSet.getSignKey();
        String apiUrl = hospitalSet.getApiUrl();
        //封装参数
        signInfoVo.setSignKey(signKey);
        signInfoVo.setApiUrl(apiUrl);

        //返回结果
        return signInfoVo;
    }

    /**
     * 根据医院名称查询
     * @param hosname
     * @return
     */
    @Override
    public List<Hospital> findByHosname(String hosname) {
        List<Hospital> hospitalList = hospitalRepository.findHospitalByHosnameLike(hosname);
        return hospitalList;
    }

    /**
     * 根据医院编号获取医院名称
     * @param hoscode
     * @return
     */
    @Override
    public String getHospNameByHoscode(String hoscode) {
        log.info("根据医院编号获取医院名称，hoscode={}", hoscode);
        Hospital hospital = hospitalRepository.getHospitalByHoscode(hoscode);
        if (hospital == null) {
            return "";
        } else {
            return hospital.getHosname();
        }
    }

    /**
     * 完善医院信息
     * @param hospital
     */
    private void setHospitalData(Hospital hospital) {
        log.info("完善医院信息...");

        //根据dict_code和value查询医院等级
        String hostypeString = dictFeignClient.getName("Hostype", hospital.getHostype());
        //查询省市区
        String provinceString = dictFeignClient.getName(hospital.getProvinceCode());
        String cityString = dictFeignClient.getName(hospital.getCityCode());
        String districtString = dictFeignClient.getName(hospital.getDistrictCode());
        //完善医院信息
        hospital.getParam().put("hostypeString", hostypeString);
        hospital.getParam().put("fullAddress", provinceString + cityString + districtString);
    }

    /**
     * 上传医院接口
     * @param paramMap
     */
    @Override
    public void save(Map<String, Object> paramMap) {
        log.info(JSONObject.toJSONString(paramMap));

        String jsonString = JSONObject.toJSONString(paramMap);
        Hospital hospital = JSON.parseObject(jsonString, Hospital.class);

        //按id查找医院
        Hospital hospitalExist = hospitalRepository.getHospitalByHoscode(hospital.getHoscode());

        if (hospitalExist == null) {
            //若医院不存在,则添加医院
            //设置状态，0：未上线，1：已上线
            hospital.setStatus(0);
            hospital.setCreateTime(new Date());
            hospital.setUpdateTime(new Date());
            hospital.setIsDeleted(0);
            hospitalRepository.save(hospital);
        } else {
            //若医院存在，则修改医院
            hospital.setStatus(hospitalExist.getStatus());
            hospital.setCreateTime(hospitalExist.getCreateTime());
            hospital.setUpdateTime(new Date());
            hospital.setIsDeleted(0);
            hospitalRepository.save(hospital);
        }
    }

    /**
     * 根据医院编码查询医院信息
     * @param hoscode
     * @return
     */
    @Override
    public Hospital getHospitalByHoscode(String hoscode) {
        return hospitalRepository.getHospitalByHoscode(hoscode);
    }
}
